/**
 * 数字相关的工具函数
 */

/**
 * 将单个数字转换为中文表示
 * @param num 需要转换的数字
 * @param options 转换选项
 * @returns 中文表示的字符串
 */
export const numToCn = (
  num: number,
  options: { big: boolean } = { big: false },
) => {
  let cn: string[];
  if (options.big) {
    cn = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
  } else {
    cn = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
  }
  return num
    .toString()
    .split('')
    .map((item) => cn[Number(item)])
    .join('');
};

/**
 * 将数字转换为中文读法字符串
 * @param num 要转换的数字
 * @returns 中文读法字符串
 * @example
 * numberToChinese(123); // "壹佰贰拾叁"
 * numberToChinese(1001); // "壹仟零壹"
 * numberToChinese(10000); // "壹万"
 */
export const numberToChinese = (num: number): string => {
  if (num === 0) return '零';

  const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
  const units = ['', '拾', '佰', '仟'];

  if (num === 0) return '零';
  const numStr = num.toString();
  if (numStr.length > 16) {
    throw new Error('数字过大，无法处理');
  }

  // 特殊处理10-19的数字
  if (num >= 10 && num <= 19) {
    const onesDigit = num % 10;
    if (onesDigit === 0) {
      return '壹拾';
    } else {
      return `壹拾${digits[onesDigit]}`;
    }
  }

  // 使用更精确的算法处理中文数字转换
  let result = '';

  // 从高位到低位处理每个数字位
  let zeroFlag = false; // 标记是否需要添加零

  for (let i = 0; i < numStr.length; i++) {
    const digit = parseInt(numStr[i]);
    const pos = numStr.length - 1 - i; // 从高位到低位的位置

    if (digit !== 0) {
      // 如果有累积的零标记，添加零
      if (zeroFlag) {
        result += '零';
        zeroFlag = false;
      }

      // 添加数字
      result += digits[digit];

      // 添加小单位（拾、佰、仟）
      const unitIndex = pos % 4;
      if (unitIndex > 0) {
        result += units[unitIndex];
      }
    } else {
      zeroFlag = true; // 标记需要零
    }

    // 处理大单位（万、亿）
    if (pos % 4 === 0 && pos > 0) {
      // 检查当前大单位对应的4位数字段是否有非零数字
      let hasNonZeroInGroup = false;
      const groupStart = Math.max(0, numStr.length - pos - 4);
      const groupEnd = numStr.length - pos;

      for (let j = groupStart; j < groupEnd && j < numStr.length; j++) {
        if (parseInt(numStr[j]) !== 0) {
          hasNonZeroInGroup = true;
          break;
        }
      }

      // 只有当当前大单位对应的4位数字段有非零数字时才添加大单位
      if (hasNonZeroInGroup) {
        if (pos === 4) {
          result += '万';
        } else if (pos === 8) {
          result += '亿';
        } else if (pos === 12) {
          result += '兆';
        }
        zeroFlag = false; // 大单位后重置零标记
      }
    }
  }

  // 清理末尾的零
  return result.replace(/零+$/, '') || '零';
};

/**
 * 将数字转换为中文表示（去零法实现）
 * 使用去零法：确定每个位数的读法，从头到尾表示，合并重复零
 * @param num 需要转换的数字
 * @returns 中文表示的数字
 * @example
 * numToCnReading(123); // "壹佰贰拾叁"
 * numToCnReading(1001); // "壹仟零壹"
 * numToCnReading(10001); // "壹万零壹"
 */
export const numToCnReading = (num: number): string => {
  if (num === 0) return '零';

  const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
  const units = ['', '拾', '佰', '仟'];
  const bigUnits = ['', '万', '亿', '兆'];

  const numStr = num.toString();
  if (numStr.length > 16) {
    throw new Error('数字过大，无法处理');
  }

  // 特殊处理10-19
  if (num >= 10 && num <= 19) {
    const onesDigit = num % 10;
    if (onesDigit === 0) {
      return '壹拾';
    } else {
      return `壹拾${digits[onesDigit]}`;
    }
  }

  let result = '';
  let prevZero = false; // 标记前一个是否是零

  // 从左到右处理每个数字位
  for (let i = 0; i < numStr.length; i++) {
    const digit = parseInt(numStr[i]);
    const pos = numStr.length - 1 - i; // 从高位到低位的位置

    if (digit !== 0) {
      // 如果之前有零标记，且当前不是最高位，添加零
      if (prevZero && i > 0) {
        result += '零';
      }

      // 添加数字
      result += digits[digit];

      // 添加小单位
      const unitIndex = pos % 4;
      if (unitIndex > 0) {
        result += units[unitIndex];
      }

      prevZero = false;
    } else {
      prevZero = true;
    }

    // 处理大单位（万、亿、兆）
    if (pos % 4 === 0 && pos > 0) {
      // 检查当前大单位对应的4位数字段是否有非零数字
      let hasNonZeroInGroup = false;
      const groupStart = Math.max(0, numStr.length - pos - 4);
      const groupEnd = numStr.length - pos;

      for (let j = groupStart; j < groupEnd && j < numStr.length; j++) {
        if (parseInt(numStr[j]) !== 0) {
          hasNonZeroInGroup = true;
          break;
        }
      }

      // 只有当当前大单位对应的4位数字段有非零数字时才添加大单位
      if (hasNonZeroInGroup) {
        const bigUnitIndex = Math.floor(pos / 4);
        if (bigUnitIndex < bigUnits.length) {
          result += bigUnits[bigUnitIndex];
        }
        prevZero = false; // 大单位后重置零标记
      }
    }
  }

  // 清理末尾的零
  return result.replace(/零+$/, '') || '零';
};
